home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gschar.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  9.9 KB  |  368 lines

  1. /* Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gschar.c,v 1.3 2000/09/19 19:00:26 lpd Exp $ */
  20. /* Character writing "operators" for Ghostscript library */
  21. #include "gx.h"
  22. #include "gserrors.h"
  23. #include "gsstruct.h"
  24. #include "gsmatrix.h"        /* for gscoord.h */
  25. #include "gscoord.h"        /* for gs_idtransform */
  26. #include "gzstate.h"
  27. #include "gxdevice.h"
  28. #include "gxdevmem.h"
  29. #include "gxchar.h"
  30. #include "gxfont.h"
  31.  
  32. /* Forward declarations */
  33. private int show_n_begin(P4(gs_show_enum *penum, gs_state *pgs, int code,
  34.                 gs_text_enum_t *pte));
  35.  
  36. /* Structure descriptors */
  37. extern_st(st_gs_show_enum);
  38.  
  39. /* ------ String writing operators ------ */
  40.  
  41. /* Free the contents of a show enumerator. */
  42. void
  43. gs_show_enum_release(gs_show_enum * penum, gs_memory_t * emem)
  44. {
  45.     if (penum->text.operation)    /* otherwise, never initialized */
  46.     penum->procs->release((gs_text_enum_t *)penum, "gs_show_enum_release");
  47.     if (emem != 0)
  48.     gs_free_object(emem, penum, "gs_show_enum_release");
  49. }
  50.  
  51. /* show[_n] */
  52. int
  53. gs_show_n_init(gs_show_enum * penum, gs_state * pgs,
  54.            const char *str, uint size)
  55. {
  56.     gs_text_enum_t *pte;
  57.     int code = gs_show_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
  58.  
  59.     return show_n_begin(penum, pgs, code, pte);
  60. }
  61.  
  62. /* ashow[_n] */
  63. int
  64. gs_ashow_n_init(gs_show_enum * penum, gs_state * pgs,
  65.         floatp ax, floatp ay, const char *str, uint size)
  66. {
  67.     gs_text_enum_t *pte;
  68.     int code = gs_ashow_begin(pgs, ax, ay, (const byte *)str, size,
  69.                   pgs->memory, &pte);
  70.  
  71.     return show_n_begin(penum, pgs, code, pte);
  72. }
  73.  
  74. /* widthshow[_n] */
  75. int
  76. gs_widthshow_n_init(gs_show_enum * penum, gs_state * pgs,
  77.             floatp cx, floatp cy, gs_char chr,
  78.             const char *str, uint size)
  79. {
  80.     gs_text_enum_t *pte;
  81.     int code = gs_widthshow_begin(pgs, cx, cy, chr, (const byte *)str, size,
  82.                   pgs->memory, &pte);
  83.  
  84.     return show_n_begin(penum, pgs, code, pte);
  85. }
  86.  
  87. /* awidthshow[_n] */
  88. int
  89. gs_awidthshow_n_init(gs_show_enum * penum, gs_state * pgs,
  90.              floatp cx, floatp cy, gs_char chr, floatp ax, floatp ay,
  91.              const char *str, uint size)
  92. {
  93.     gs_text_enum_t *pte;
  94.     int code = gs_awidthshow_begin(pgs, cx, cy, chr, ax, ay,
  95.                    (const byte *)str, size, pgs->memory, &pte);
  96.  
  97.     return show_n_begin(penum, pgs, code, pte);
  98. }
  99.  
  100. /* kshow[_n] */
  101. int
  102. gs_kshow_n_init(gs_show_enum * penum,
  103.         gs_state * pgs, const char *str, uint size)
  104. {
  105.     gs_text_enum_t *pte;
  106.     int code;
  107.  
  108.     switch (pgs->font->FontType) {
  109.     case ft_composite:
  110.     case ft_CID_encrypted:
  111.     case ft_CID_user_defined:
  112.     case ft_CID_TrueType:
  113.     case ft_CID_bitmap:
  114.     return_error(gs_error_invalidfont);
  115.     default:
  116.     break;
  117.     }
  118.     code = gs_kshow_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
  119.     return show_n_begin(penum, pgs, code, pte);
  120. }
  121.  
  122. /* xyshow[_n] */
  123. int
  124. gs_xyshow_n_init(gs_show_enum * penum,
  125.          gs_state * pgs, const char *str, uint size)
  126. {
  127.     gs_text_enum_t *pte;
  128.     int code = gs_xyshow_begin(pgs, (const byte *)str, size, NULL, NULL, 0,
  129.                    pgs->memory, &pte);
  130.  
  131.     return show_n_begin(penum, pgs, code, pte);
  132. }
  133.  
  134. /* glyphshow */
  135. int
  136. gs_glyphshow_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph)
  137. {
  138.     gs_text_enum_t *pte;
  139.     int code = gs_glyphshow_begin(pgs, glyph, pgs->memory, &pte);
  140.  
  141.     return show_n_begin(penum, pgs, code, pte);
  142. }
  143. int
  144. gs_glyphpath_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph,
  145.           bool stroke_path)
  146. {
  147.     gs_text_enum_t *pte;
  148.     int code = gs_glyphpath_begin(pgs, glyph, stroke_path, pgs->memory, &pte);
  149.  
  150.     return show_n_begin(penum, pgs, code, pte);
  151. }
  152. int
  153. gs_glyphwidth_init(gs_show_enum * penum, gs_state * pgs, gs_glyph glyph)
  154. {
  155.     gs_text_enum_t *pte;
  156.     int code = gs_glyphwidth_begin(pgs, glyph, pgs->memory, &pte);
  157.  
  158.     return show_n_begin(penum, pgs, code, pte);
  159. }
  160.  
  161. /* ------ Related operators ------ */
  162.  
  163. /* cshow[_n] */
  164. int
  165. gs_cshow_n_init(gs_show_enum * penum,
  166.         gs_state * pgs, const char *str, uint size)
  167. {
  168.     gs_text_enum_t *pte;
  169.     int code = gs_cshow_begin(pgs, (const byte *)str, size, pgs->memory, &pte);
  170.  
  171.     return show_n_begin(penum, pgs, code, pte);
  172. }
  173.  
  174. /* stringwidth[_n] */
  175. int
  176. gs_stringwidth_n_init(gs_show_enum * penum, gs_state * pgs,
  177.               const char *str, uint size)
  178. {
  179.     gs_text_enum_t *pte;
  180.     int code = gs_stringwidth_begin(pgs, (const byte *)str, size,
  181.                     pgs->memory, &pte);
  182.  
  183.     return show_n_begin(penum, pgs, code, pte);
  184. }
  185.  
  186. /* charpath[_n] */
  187. int
  188. gs_charpath_n_init(gs_show_enum * penum, gs_state * pgs,
  189.            const char *str, uint size, bool stroke_path)
  190. {
  191.     gs_text_enum_t *pte;
  192.     int code = gs_charpath_begin(pgs, (const byte *)str, size, stroke_path,
  193.                  pgs->memory, &pte);
  194.  
  195.     return show_n_begin(penum, pgs, code, pte);
  196. }
  197.  
  198. /* charboxpath[_n] */
  199. int
  200. gs_charboxpath_n_init(gs_show_enum * penum, gs_state * pgs,
  201.               const char *str, uint size, bool use_boxes)
  202. {
  203.     gs_text_enum_t *pte;
  204.     int code = gs_charboxpath_begin(pgs, (const byte *)str, size, use_boxes,
  205.                     pgs->memory, &pte);
  206.  
  207.     return show_n_begin(penum, pgs, code, pte);
  208. }
  209.  
  210. /* ------ Width/cache operators ------ */
  211.  
  212. /* setcachedevice */
  213. /* The elements of pw are: wx, wy, llx, lly, urx, ury. */
  214. /* Note that this returns 1 if we just set up the cache device. */
  215. int
  216. gs_setcachedevice_double(gs_show_enum *penum, gs_state *pgs, const double *pw)
  217. {
  218.     if (penum->pgs != pgs)
  219.     return_error(gs_error_rangecheck);
  220.     return gs_text_setcachedevice((gs_text_enum_t *)penum, pw);
  221. }
  222. /* The _float procedure is strictly for backward compatibility. */
  223. int
  224. gs_setcachedevice_float(gs_show_enum * penum, gs_state * pgs, const float *pw)
  225. {
  226.     double w[6];
  227.     int i;
  228.  
  229.     for (i = 0; i < 6; ++i)
  230.     w[i] = pw[i];
  231.     return gs_setcachedevice_double(penum, pgs, w);
  232. }
  233.  
  234. /* setcachedevice2 */
  235. /* The elements of pw2 are: w0x, w0y, llx, lly, urx, ury, w1x, w1y, vx, vy. */
  236. /* Note that this returns 1 if we just set up the cache device. */
  237. int
  238. gs_setcachedevice2_double(gs_show_enum * penum, gs_state * pgs,
  239.               const double *pw2)
  240. {
  241.     if (penum->pgs != pgs)
  242.     return_error(gs_error_rangecheck);
  243.     return gs_text_setcachedevice2((gs_text_enum_t *)penum, pw2);
  244. }
  245. /* The _float procedure is strictly for backward compatibility. */
  246. int
  247. gs_setcachedevice2_float(gs_show_enum * penum, gs_state * pgs, const float *pw2)
  248. {
  249.     double w2[10];
  250.     int i;
  251.  
  252.     for (i = 0; i < 10; ++i)
  253.     w2[i] = pw2[i];
  254.     return gs_setcachedevice2_double(penum, pgs, w2);
  255. }
  256.  
  257. /* setcharwidth */
  258. /* Note that this returns 1 if the current show operation is */
  259. /* non-displaying (stringwidth or cshow). */
  260. int
  261. gs_setcharwidth(gs_show_enum * penum, gs_state * pgs,
  262.         floatp wx, floatp wy)
  263. {
  264.     double w[2];
  265.  
  266.     if (penum->pgs != pgs)
  267.     return_error(gs_error_rangecheck);
  268.     w[0] = wx, w[1] = wy;
  269.     return gs_text_setcharwidth((gs_text_enum_t *)penum, w);
  270. }
  271.  
  272. /* ------ Enumerator ------ */
  273.  
  274. /* Do the next step of a show (or stringwidth) operation */
  275. int
  276. gs_show_next(gs_show_enum * penum)
  277. {
  278.     return gs_text_process((gs_text_enum_t *)penum);
  279. }
  280.  
  281. /*
  282.  * Return true if we only need the width from the rasterizer
  283.  * and can short-circuit the full rendering of the character,
  284.  * false if we need the actual character bits.
  285.  */
  286. bool
  287. gs_show_width_only(const gs_show_enum * penum)
  288. {
  289.     return gs_text_is_width_only((const gs_text_enum_t *)penum);
  290. }
  291.  
  292. /* ------ Accessors ------ */
  293.  
  294. /* Return the current character for rendering. */
  295. gs_char
  296. gs_show_current_char(const gs_show_enum * penum)
  297. {
  298.     return gs_text_current_char((const gs_text_enum_t *)penum);
  299. }
  300.  
  301. /* Return the current glyph for rendering. */
  302. gs_glyph
  303. gs_show_current_glyph(const gs_show_enum * penum)
  304. {
  305.     return gs_text_current_glyph((const gs_text_enum_t *)penum);
  306. }
  307.  
  308. /* Return the width of the just-enumerated character (for cshow). */
  309. int
  310. gs_show_current_width(const gs_show_enum * penum, gs_point * ppt)
  311. {
  312.     return gs_text_current_width((const gs_text_enum_t *)penum, ppt);
  313. }
  314.  
  315. /* Return the just-displayed character for kerning. */
  316. gs_char
  317. gs_kshow_previous_char(const gs_show_enum * penum)
  318. {
  319.     return gs_text_current_char((const gs_text_enum_t *)penum);
  320. }
  321.  
  322. /* Return the about-to-be-displayed character for kerning. */
  323. gs_char
  324. gs_kshow_next_char(const gs_show_enum * penum)
  325. {
  326.     return penum->text.data.bytes[penum->index];
  327. }
  328.  
  329. /* Return the accumulated width for stringwidth. */
  330. void
  331. gs_show_width(const gs_show_enum * penum, gs_point * ppt)
  332. {
  333.     gs_text_total_width((const gs_text_enum_t *)penum, ppt);
  334. }
  335.  
  336. /* ------ Internal routines ------ */
  337.  
  338. /*
  339.  * Force the enumerator to be a gs_show_enum *, which the current
  340.  * implementation code requires.
  341.  */
  342. private int
  343. show_n_begin(gs_show_enum *penum, gs_state *pgs, int code, gs_text_enum_t *pte)
  344. {
  345.     if (code < 0)
  346.     return code;
  347.     if (gs_object_type(pgs->memory, pte) != &st_gs_show_enum) {
  348.     /* Use the default implementation. */
  349.     gx_device *dev = pgs->device;
  350.     gs_text_params_t text;
  351.     gs_memory_t *mem = pte->memory;
  352.     dev_proc_text_begin((*text_begin)) = dev_proc(dev, text_begin);
  353.  
  354.     text = pte->text;
  355.     gs_text_release(pte, "show_n_begin");
  356.     /* Temporarily reset the text_begin procedure to the default. */
  357.     set_dev_proc(dev, text_begin, gx_default_text_begin);
  358.     code = gs_text_begin(pgs, &text, mem, &pte);
  359.     set_dev_proc(dev, text_begin, text_begin);
  360.     if (code < 0)
  361.         return code;
  362.     }
  363.     /* Now we know pte points to a gs_show_enum. */
  364.     *penum = *(gs_show_enum *)pte;
  365.     gs_free_object(pgs->memory, pte, "show_n_begin");
  366.     return code;
  367. }
  368.